from .models import Student, Teacher, Register, Class
from django.http.response import JsonResponse
from django.http import HttpRequest, HttpResponse
from django.core import serializers
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
import json
import logging
from django.core.exceptions import ObjectDoesNotExist
from django.db import IntegrityError
from django.http.request import QueryDict
from django.utils import timezone
from .util import strToSet, setToStr, getDictFormSession
from mysite import settings
import os

logger = logging.getLogger('django.request')

def teacher(request):
    if request.method == 'GET':
        data = {}
        teachers = Teacher.objects.order_by('id').values()
        tid = request.GET.get('id',None)
        if tid is not None:
            data['data'] = list(teachers.filter(id=tid))
        else:
            data['data'] = list(teachers)
        logger.warning(data['data'])
        return JsonResponse(data)  # 须为dict类型 不能是data['list']
    
    # 使用django自己的后台添加老师和学生
    """ elif request.method == 'POST':
        # 带有id且已经存在时为更新记录 不带有id或数据库中不存在此id为新建记录
        newTech = Teacher()
        newTech.initFromDict(request.POST)
        logger.warning("POST Teacher")
        newTech.save()
        logger.warning("修改成功")
        return JsonResponse(newTech.toDict())
        # return JsonResponse() 待清楚参数要求 """

def student(request):
    if request.method == 'GET':
        data = {}
        students = Student.objects.order_by('num').values('id', 'name', 'num')
        # students = Student.objects.order_by('num').values('id', 'name', 'num') # 返回指定字段
        # 支持获取指定学号的学生 /api/students?num=18101
        num = request.GET.get('num',None)
        if num is not None:
            data['data'] = list(students.filter(num=num))
        else:
            data['data'] = list(students)
        logger.warning(data['data'])
        data['code'] = 0
        data['msg'] = ""
        data['count'] = len(data['data'])
        return JsonResponse(data) # 须为dict类型 不能是data['list']

    """ elif request.method == 'POST':
        # 带有id且已经存在时为更新记录 不带有id或数据库中不存在此id为新建记录
        newStu = Student()
        newStu.initFromDict(request.POST)
        logger.warning("POST Student")
        newStu.save()
        logger.warning("修改成功")
        return JsonResponse(newStu.toDict())
        # return JsonResponse() 待清楚参数要求 """

def clas(request):
    if request.method == 'GET':
        data = {}
        classes = Class.objects.order_by('id').values()
        cid = request.GET.get('id',None)
        if cid is not None:
            data['data'] = list(classes.filter(id=cid))
        else:
            data['data'] = list(classes)
        logger.warning(data['data'])
        return JsonResponse(data) # 须为dict类型 不能是data['list']

    elif request.method == 'POST':
        newCls = Class()
        teacher = request.POST.get('teacher', 'invalid')
        name = request.POST.get('name', 'invalid')
        other = request.POST.get('other', '1') # 可选参数
        if teacher == 'invalid' or name == 'invalid':
            return JsonResponse({'result': 'incomplete information'})
        try:
            t = Teacher.objects.get(username=teacher)
        except ObjectDoesNotExist as e:
            logger.error(e)
            return JsonResponse({"result": "no-exist-teacher"})
        logger.warning("POST Class")
        newCls.classname = teacher + "-" + name + "-" + other
        newCls.teacher = t
        try:
            newCls.save()
        except IntegrityError as e:
            logger.error(e)
            return JsonResponse({"result": "dulicate-classname"})
        logger.warning("创建班级成功")
        resp = newCls.toDict()
        resp["result"] = "create-class-success"
        return JsonResponse(resp)

    # 注意 PUT方法提交时 客户端要使用x-www-form-urlencoded 而不是form-data
    elif request.method == 'PUT':  # 仅支持向班级中添加学生（提供id）
        put = QueryDict(request.body)
        logger.warning(str(put))
        studentids = put.get('studentids', 'invalid')
        classname = put.get('classname', 'invalid')
        if studentids == 'invalid' or classname == 'invalid':
            return JsonResponse({"result": "nothing-change"})
        logger.warning(classname + " :: "+studentids)
        try:
            t = Class.objects.get(classname=classname)
        except ObjectDoesNotExist:
            return JsonResponse({"result": "no-exist-class"})
        
        idSet = strToSet(t.students) # 数据库中已有的id
        addIds = strToSet(studentids).difference(idSet)  # 需新增的id
        logger.warning("add ids: "+str(addIds))
        for s in addIds: # 对每个学生id进行检查 合法的依次保存 遇到第一个不存在的就退出
            try:
                student = Student.objects.get(id=int(s))
                classSet = strToSet(student.classes)
                classSet.add(str(t.id)) # 更新学生的班级列表
                student.classes = setToStr(classSet)
                student.save()
                idSet.add(s) # 更新班级的学生列表
            except ObjectDoesNotExist:
                t.students = setToStr(idSet)
                t.save()
                return JsonResponse({"result": "no-exist-student","id":s})
        t.students = setToStr(idSet)
        t.save()
        return JsonResponse(t.toDict())

def register(request):
    if request.method == 'GET':
        data = {}
        registers = Register.objects.order_by('id')
        classid = request.GET.get('classid', None)
        student_id = request.GET.get('student_id', None)
        limit = request.GET.get('limit', 100)
        pagenum = request.GET.get('page', 1)
        result = request.GET.get('result', 'invalid')
        if classid is not None:
            registers = registers.filter(clas=int(classid))
        else:
            logger.warning("lack-classid")
            return JsonResponse({"result":"lack-classid"})
        if student_id is not None and len(student_id) != 0:
            registers = registers.filter(student=int(student_id))
        else:
            info = getDictFormSession(request.session)
            if info['loginType'] == 'student' and info['loginId'] != 'invalid':
                logger.warning("学生用户 自动设置student_id")
                registers = registers.filter(student=int(info['loginId']))
        if result != 'invalid' and result != '':
            registers = registers.filter(result=result)
        paginator = Paginator(registers, limit)  # 生成分页实例
        try:
            page_res = paginator.page(pagenum)
        except PageNotAnInteger:
            page_res = paginator.page(1)
        except EmptyPage:
            page_res = paginator.page(1)
        L = []
        for p in page_res:
            L.append(p.toDict())
        data['data'] = L
        data['code'] = 0
        data['msg'] = ""
        data['count'] = paginator.count
        return JsonResponse(data)  # 须为dict类型 不能是data['list']

    elif request.method == "POST":
        classname = request.POST.get('classname', 'invalid')
        if classname == 'invalid':
            return JsonResponse({'result': 'invalid'})
        try:
            clas = Class.objects.get(classname=classname)
        except ObjectDoesNotExist:
            return JsonResponse({"result": "no-exist-class"})
        students = strToSet(clas.students)
        time = timezone.now()
        logger.warning(str(time))
        for s in students:
            oneRegister = Register(student=Student.objects.get(id=int(s)), clas=clas, create_time=time, time=time, result="未签到")
            oneRegister.save()
        return JsonResponse({"result": "created-one-register"})
    
    elif request.method == 'PUT':
        put = QueryDict(request.body)
        logger.warning(str(put))
        registerids = put.get('registerids', 'invalid')
        result = put.get('result', 'invlid')
        if registerids == 'invalid' or result == 'invalid':
            logger.warning("invlid: registerids or result")
            return JsonResponse({"result": "nothing-change"})
        logger.warning(registerids + " :: "+result)
        idSet = strToSet(registerids)
        for s in idSet: # 对每个register id进行检查 合法的依次修改 遇到第一个不存在的就退出
            try:
                oneReg = Register.objects.get(id=int(s))
                oneReg.result = result
                oneReg.save()
            except ObjectDoesNotExist:
                return JsonResponse({"result": "no-exist-register","id":s})
        return JsonResponse({"result": "change-result-success"})

def login(request):
    if request.method == 'POST':
        username = request.POST.get('username', 'invalid')
        password = request.POST.get('password', 'invalid')
        loginType = request.POST.get('loginType', 'invalid')
        logger.warning(username + "  "+password+"  "+ loginType)
        try:
            if loginType == 'teacher':
                request.session['loginType'] = 'teacher'
                t = Teacher.objects.get(username=username)
            else:
                request.session['loginType'] = 'student'
                t = Student.objects.get(num=username)
        except ObjectDoesNotExist:
            return JsonResponse({"result": "no-exist"})
        if t.password == password:
            request.session['loginName'] = username
            request.session['loginId'] = t.id
            return JsonResponse({"result": "login-success"})
        else:
            return JsonResponse({"result": "login-password-wrong"})

def signOut(request):
    request.session.flush()
    return JsonResponse({"result":"signed out"})

def upload(request):
    if request.method == "POST":
        resp = {
            "code": 0,
            "msg": "",
            "data": {},
        }
        myFile = request.FILES.get("file", None)
        if myFile:
            dir = os.path.join(settings.BASE_DIR, 'aiAttendance\\static\\profiles')
            filename = request.session.get('loginName')
            dir = os.path.join(dir, filename+os.path.splitext(myFile.name)[-1])
            destination = open(dir,'wb+')
            for chunk in myFile.chunks():
                 destination.write(chunk)
            destination.close()
            resp['msg'] = "upload success"
        else:
            resp['msg'] = "no exist file"
        return JsonResponse(resp)

def doregister(request):
    if request.method == 'POST':

        registerid = request.POST.get('registerid', 'invalid')
        if registerid == 'invalid':
            return JsonResponse({"result": "invalid-registerid"})
        try:
            register = Register.objects.get(id=int(registerid))
        except ObjectDoesNotExist:
            return JsonResponse({"result": "no-exist-register"})
        if int(request.session.get('loginId', '-1')) == register.student.id:
            register.result = '出勤'
            register.time = timezone.now()
            register.save()
            return JsonResponse({"result": "register-done"})
        else:
            return JsonResponse({"result": "wrong-student"})


